home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Megahits 5
/
Megahits 5 (1994)(GTI - Rhein-Main-Soft)(DE)(Disc 2 of 2)[!].iso
/
archive
/
show
/
jmore03.lzh
/
jmoresrc.LZH
/
jFontSys.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-11-04
|
7KB
|
369 lines
/*
* jFontSys.c
* H.Ohkubo Oct. 19, 1992
*/
#include <exec/types.h>
#include <exec/ports.h>
#include <graphics/text.h>
#include <functions.h>
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <string.h>
#include <ctype.h>
#include "jFont.h"
#include "jFontSys.h"
#include "openlib.h"
struct MsgPort *jFontPort = NULL;
struct TextAttr textattr = {
NULL, /* set font name, later */
FONT_SIZE, /* font height */
FS_NORMAL, /* style is normal. not bold, not italic, not... */
FPF_DISKFONT, /* this is Disk font. */
};
struct font_cache cache[FONT_CACHE_MAX], cache_list;
int cache_size = FONT_CACHE_SIZE;
BOOL denec = FALSE;
char jfontname[FNAMELEN];
#ifdef DEBUG
int cache_hit = 0, cache_missed = 0; /* for font cache effect check */
#endif
/* prototypes */
struct TextFont *open_font(USHORT);
struct TextFont *open_font_doit(char *);
VOID insert_font(struct font_cache *, struct font_cache *);
struct font_cache *remove_font(struct font_cache *);
VOID init_font_cache(VOID);
VOID free_font_cache(VOID);
struct MsgPort *set_jfont(VOID);
VOID remove_jfont(struct MsgPort *, BOOL);
VOID get_startup(VOID);
VOID init_default(VOID);
int set_startup_value(FILE *);
char *my_getline(FILE *);
int set_cache_size(int);
VOID clean_exit(char *, int);
VOID main(int argc, char *argv[])
{
struct jFontMsg *msg;
int done = FALSE;
BOOL fromwb = TRUE;
if (argc != 0) {
puts(COPYRIGHT);
fromwb = FALSE;
}
if ((jFontPort = FindPort(JFONTPORT)) != NULL)
remove_jfont(jFontPort, fromwb);
else {
jFontPort = set_jfont();
if (!OpenLib())
clean_exit("No Library !", RETURN_FAIL);
}
get_startup();
init_font_cache();
while (!done) {
WaitPort(jFontPort);
while (msg = (struct jFontMsg *)GetMsg(jFontPort)) {
switch (msg->kanji) {
case REMOVE_JFONT:
while (msg = (struct jFontMsg *)GetMsg(jFontPort)) {
msg->font = (struct TextFont *)NULL;
ReplyMsg((struct Message *)msg);
}
done = TRUE;
break;
default:
msg->font = (struct TextFont *)open_font(msg->kanji);
ReplyMsg((struct Message *)msg);
break;
}
}
}
free_font_cache();
clean_exit(END_MESSAGE, RETURN_OK);
}
/* for font cache routine */
struct TextFont *open_font(USHORT kanji_code)
{
int fontnum;
char fontname[FNAMELEN];
/* kanji_code is JIS kanji-code. but this is illegal case. */
if (kanji_code == ANK_FONT_CODE)
return cache[ANK].font;
fontnum = ((kanji_code>>CHAR_BIT)&0xff) - ' '; /* get font file number */
if (fontnum >= SYM1 && fontnum <= KATA)
return cache[fontnum].font;
if (denec && (fontnum > KEISEN && fontnum < JIS1)) /* NEC local? or not */
return (struct TextFont *)NULL;
sprintf(fontname, KNJ_FONT, KANJIDIR, jfontname, fontnum);
return open_font_doit(fontname);
}
struct TextFont *open_font_doit(char *fontname)
{
struct font_cache *p = &cache_list;
struct TextFont *font;
for (p = p->next; p != &cache_list; p = p->next) {
if (strcmp(fontname, p->fontname) == 0) {
#ifdef DEBUG
cache_hit++;
#endif
remove_font(p);
insert_font(&cache_list, p);
return p->font;
}
}
p = remove_font(cache_list.next);
insert_font(&cache_list, p);
if (p->font) {
CloseFont(p->font);
p->font = (struct TextFont *)NULL;
p->fontname[0] = '\0';
}
textattr.ta_Name = (STRPTR)fontname;
if ((font = OpenDiskFont(&textattr)) == NULL)
return (struct TextFont *)NULL;
p->font = font;
strcpy(p->fontname, fontname);
#ifdef DEBUG
cache_missed++;
#endif
return font;
}
VOID insert_font(struct font_cache *position, struct font_cache *x)
{
position->prev->next = x;
x->prev = position->prev;
x->next = position;
position->prev = x;
}
struct font_cache *remove_font(struct font_cache *x)
{
x->prev->next = x->next;
x->next->prev = x->prev;
return x;
}
VOID init_font_cache(VOID)
{
int i;
for (i = ANK; i <= KATA; i++) {
if (i == ANK && *(cache[i].fontname) == '\0')
sprintf(cache[i].fontname, ANK_FONT);
else if (*(cache[i].fontname) == '\0')
sprintf(cache[i].fontname, KNJ_FONT, KANJIDIR, jfontname, i);
textattr.ta_Name = (STRPTR)cache[i].fontname;
if ((cache[i].font = OpenDiskFont(&textattr)) == NULL) {
free_font_cache();
clean_exit("No Font !", RETURN_FAIL);
}
cache[i].next = cache[i].prev = &cache[i];
}
cache_list.next = cache_list.prev = &cache_list;
for (; i < cache_size; i++) {
cache[i].font = (struct TextFont *)NULL;
insert_font(&cache_list, &cache[i]);
}
}
VOID free_font_cache(VOID)
{
int i;
for (i = 0; i < cache_size; i++) {
if (cache[i].font)
CloseFont(cache[i].font);
}
#ifdef DEBUG
printf("Cache Hit = %d\tCache missed = %d\n", cache_hit, cache_missed);
#endif
}
/* for Message port routine */
struct MsgPort *set_jfont(VOID)
{
struct MsgPort *port;
if ((port = CreatePort(JFONTPORT, NORMAL_PRI)) == NULL)
clean_exit("No Port !", RETURN_FAIL);
return port;
}
VOID remove_jfont(struct MsgPort *jFontPort, BOOL fromwb)
{
struct jFontMsg sendmsg;
sendmsg.msg.mn_Length = sizeof(struct jFontMsg);
sendmsg.kanji = REMOVE_JFONT;
PutMsg(jFontPort, (struct Message *)&sendmsg);
if (!fromwb)
puts(REMOVE_MESSAGE);
exit(EXIT_SUCCESS);
}
/* for startup file routine */
VOID get_startup(VOID)
{
FILE *fp;
init_default();
if ((fp = fopen(STARTUP, READ_BINARY)) != NULL) {
while (set_startup_value(fp) != EOF)
;
fclose(fp);
}
}
int set_startup_value(FILE *fp)
{
char *lp, *name_end, *value_head;
int i, c;
lp = my_getline(fp);
if ((name_end = strchr(lp, '=')) != NULL) {
value_head = name_end + 1;
for (i = CACHE_SIZE; i < TOTAL_STARTUP; i++) {
if (strncmp(startup[i], lp, name_end - lp) == 0) {
switch (i) {
case CACHE_SIZE:
cache_size = set_cache_size(atoi(value_head));
break;
case FONT_NAME:
sprintf(cache[ANK].fontname,
"%s.font", value_head);
break;
case JFONT_NAME:
strcpy(jfontname, value_head);
break;
case SYM1_NAME:
case SYM2_NAME:
case JANK_NAME:
case HIRA_NAME:
case KATA_NAME:
sprintf(cache[i - SYM1_NAME + 1].fontname,
"%s%s.font", KANJIDIR, value_head);
break;
default:
break;
}
}
}
}
else if (strlen(lp) > 0) {
if (strcmp(startup[DENEC], lp) == 0)
denec = TRUE;
}
c = fgetc(fp);
ungetc(c, fp); /* for check EOF */
return c;
}
#define LINEBUFLEN 80
#define LF '\n' /* line feed */
char *my_getline(FILE *fp)
{
int c, iscomment = FALSE;
static char linebuf[LINEBUFLEN], *lp;
lp = linebuf;
while ((c = fgetc(fp)) != LF && c != EOF) {
if (!iscomment && isgraph(c)) {
switch (c) {
case COMMENT_MARK:
iscomment = TRUE;
break;
default:
if (islower(c))
c = toupper(c);
*lp++ = (char)c;
break;
}
}
}
*lp = '\0'; /* terminate */
return linebuf;
}
VOID init_default(VOID)
{
int i;
denec = FALSE;
cache_size = FONT_CACHE_SIZE;
strcpy(jfontname, JFONT); /* set default kanji font name */
for (i = ANK; i <= KATA; i++)
*cache[i].fontname = '\0'; /* set no name */
}
int set_cache_size(int cache_size)
{
if (cache_size < FONT_CACHE_MIN)
cache_size = FONT_CACHE_MIN;
else if (cache_size > FONT_CACHE_MAX)
cache_size = FONT_CACHE_MAX;
return cache_size;
}
/* free all resources, and exit this program. */
VOID clean_exit(char *mes, int exit_val)
{
if (jFontPort)
DeletePort(jFontPort);
CloseLib();
if (*mes)
fprintf(stderr, "%s\n", mes);
exit(exit_val);
}